<template>
    <div class="app-container">
        <el-row :gutter="20">
            <el-col :xs="24" :sm="9" :md="7" :lg="5">
                <div class="grid-content bg-purple">
                    <el-input v-model="searchMsg" placeholder="请输入菜单名称"></el-input>
                </div>
            </el-col>
            <el-col :xs="12" :sm="10" :md="10" :lg="10">
                <div class="grid-content bg-purple-light">
                    <el-button type="primary" icon="search" @click="filterData">搜索</el-button>
                </div>
            </el-col>
            <el-col :xs="12" :sm="5" :md="7" :lg="9" v-if="isAdmin">
                <div class="grid-content bg-purple-light" style="float:right">
                    <el-button icon="edit" @click="createMenu">新建菜单</el-button>
                </div>
            </el-col>
        </el-row>
        <!-- 菜单管理表格 -->
        <el-table :data="infos.pageData" v-loading.body="listLoading" element-loading-text="加载中..." border style="width: 100%;margin:20px 0">
            <el-table-column label="序号" min-width="80px">
                <template scope="scope">
                    <span>{{ scope.$index+1+(pageConfig.curPage-1)*pageConfig.size }}</span>
                </template>
            </el-table-column>
            <el-table-column label="菜单名称" min-width="140px">
                <template scope="scope">
                    <span>{{ scope.row.menuName }}</span>
                </template>
            </el-table-column>
            <el-table-column label="图标" min-width="80px">
                <template scope="scope">
                    <el-icon :name="scope.row.icon"></el-icon>
                </template>
            </el-table-column>
            <el-table-column label="上级菜单" min-width="120px">
                <template scope="scope">
                    <span>{{ scope.row.parentName }}</span>
                </template>
            </el-table-column>
            <el-table-column label="菜单顺序" min-width="160px">
                <template scope="scope">
                    <span style="display:inline-block;width:60px">{{ scope.row.sort }}</span>
                    <el-button :disabled="scope.row.sort=='1'" class="icon-btn" size="small" @click="sortChange(scope.row,'up')">
                        <icon name="long-arrow-up"></icon>
                    </el-button>
                    <el-button class="icon-btn" size="small" @click="sortChange(scope.row,'down')">
                        <icon name="long-arrow-down"></icon>
                    </el-button>
                </template>
            </el-table-column>
            <el-table-column label="菜单状态" min-width="100px">
                <template scope="scope">
                    <span :class="scope.row.useTag==='1'?'infoColor':'silverColor'">{{ scope.row.useTag==="1"?"启用":"停用" }}</span>
                </template>
            </el-table-column>
            <el-table-column label="操作" min-width="200px">
                <template scope="scope">
                    <el-button size="small" type="success" @click="editMenu(scope.row)" :disabled="scope.row.useTag==='0'">编辑</el-button>
                    <el-button size="small" :type="scope.row.useTag==='1'?'':'info'" @click="stateSwitch(scope,scope.row.useTag==='1'?'0':'1')">{{scope.row.useTag==="1"?"停用":"启用"}}</el-button>
                    <el-button size="small" type="danger" @click="deleteConfirm(scope.row)">删除</el-button>
                </template>
            </el-table-column>
        </el-table>
        <!-- 分页 -->
        <div class="block">
            <el-pagination style="padding:0;" @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page.sync="pageConfig.curPage" :page-size="pageConfig.size" layout="total, prev, pager, next, jumper" :total="pageConfig.total">
            </el-pagination>
        </div>
        <!-- dialog编辑框 -->
        <el-dialog title="菜单信息" size="tiny" :visible.sync="menuEditVisible">
            <el-form :model="menuInfo" style="margin-bottom:-30px" :rules="rules" ref="menuInfo">
                <el-form-item label="上级菜单" :label-width="formLabelWidth" prop="parentId">
                    <el-select v-model="menuInfo.parentId" placeholder="请选择上级菜单" :style="inputWidth" :disabled="menuInfo.disabled">
                        <el-option v-for="list in preMenuLists" :key="list.menuId" :label="list.menuName" :value="list.menuId"></el-option>
                    </el-select>
                </el-form-item>
                <el-form-item label="菜单名称" :label-width="formLabelWidth" prop="menuName" required>
                    <el-input v-model="menuInfo.menuName" auto-complete="off" :style="inputWidth" placeholder="请输入菜单名称"></el-input>
                </el-form-item>
                <el-form-item label="菜单图标" :label-width="formLabelWidth" prop="icon">
                    <el-input v-model="menuInfo.icon" auto-complete="off" :style="inputWidth" placeholder="请输入图标编码"></el-input>
                </el-form-item>
                <el-form-item label="菜单地址" :label-width="formLabelWidth" prop="menuUrl">
                    <el-input v-model="menuInfo.menuUrl" auto-complete="off" :style="inputWidth" placeholder="请输入菜单地址"></el-input>
                </el-form-item>
                <el-form-item label="菜单顺序" :label-width="formLabelWidth" prop="sort">
                    <el-input v-model.number="menuInfo.sort" auto-complete="off" :style="inputWidth" :disabled="menuInfo.disabled" placeholder="请输入菜单顺序"></el-input>
                </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button @click="menuEditVisible = false">取 消</el-button>
                <el-button type="primary" @click="submitForm('menuInfo',menuInfo.type )">确 定</el-button>
            </div>
        </el-dialog>
    
    </div>
</template>

<style>
.infoColor {
    color: #58B7FF
}

.silverColor {
    color: #8492A6
}

.icon-btn {
    padding: 3px 3px;
    vertical-align: middle
}
</style>

<script>
export default {
    data() {
        // 菜单格式及是否存在的判断
        var existSort = (rule, value, callback) => {
            if (this.menuInfo.type === 'edit') { callback() }
            if (value === '') {
                callback(new Error('请输入菜单顺序'));
            }
            setTimeout(() => {
                if (!Number.isInteger(value)) {
                    callback(new Error('请输入数字值'));
                } else {
                    if (value < 1) {
                        callback(new Error('数值不小于1'));
                    } else {
                        if (this.menuInfo.parentId === '') {
                            callback(new Error('请先选择上级菜单'));
                        } else {
                            let _url =  '/sys/menu/sameOrder/' + this.menuInfo.parentId + '/' + value;
                            this.$http.get(_url)
                                .then((response) => {
                                    if (response.code === 0) {
                                        if (response.data === 0) {
                                            callback();
                                        } else {
                                            callback(new Error('该序号已存在，请重新输入!'));
                                        }
                                    } else {
                                        callback(new Error('请求错误!'));
                                    }
                                }).catch((response) => {
                                    callback(new Error('错误'));
                                })
                        }
                    }
                }
            }, 500);
        };
        // 菜单排序的已存在判断
        var existName = (rule, value, callback) => {
            if (this.menuInfo.type === 'edit') { callback() }
            if (!value) {
                callback(new Error('请输入菜单名称'));
            }
            setTimeout(() => {
                if (value.toString().length < 3 || value.toString().length > 8) {
                    callback(new Error('长度在不超过 20 个字符'));
                } else {
                    if (this.menuInfo.parentId === '') {
                        callback(new Error('请先选择上级菜单'));
                    } else {
                        let _url =  '/sys/menu/sameName/' + this.menuInfo.parentId + '/' + value;
                        this.$http.get(_url)
                            .then((response) => {
                                if (response.code === 0) {
                                    if (response.data === 0) {
                                        callback();
                                    } else {
                                        callback(new Error('该名称已存在，请重新输入!'));
                                    }
                                } else {
                                    callback(new Error('请求错误!'));
                                }
                            }).catch((response) => {
                                callback(new Error('错误'));
                            })
                    }
                }
            }, 500);
        };
        return {
            // 权限用于能否使用新建功能
            isAdmin: false,
            listLoading: true,
            formLabelWidth: '100px',
            searchMsg: '',
            menuEditVisible: false,
            infos: {
                tableData: [],
                re_tableData: [],
                pageData: []
            },
            pageConfig: {
                curPage: 1,
                total: null,
                size: 9,
            },
            preMenuLists: [],
            menuInfo: {
                menuName: '',
                menuUrl: '',
                parentId: '',
                sort: '',
                icon: '',
                disabled: false,
                type: ''
            },
            inputWidth: {
                width: '90%'
            },
            rules: {
                menuName: [
                    { validator: existName, trigger: 'blur' }
                ],
                menuUrl: [
                    { required: true, message: '请输入菜单地址', trigger: 'blur' },
                    { min: 1, max: 500, message: '长度在不超过 500 个字符', trigger: 'blur' }
                ],
                parentId: [
                    { required: true, message: '请选择上级菜单', trigger: 'change' }
                ],
                sort: [
                    { validator: existSort, trigger: 'blur' }
                ],
                icon: [
                    { required: true, message: '请输入图标编码', trigger: 'blur' },
                    { min: 1, max: 50, message: '长度在不超过 50 个字符', trigger: 'blur' }
                ]
            },
        }
    },
    created() {
        this.getMenuList();
    },
    methods: {
        getMenuList() {
            this.listLoading = true;
            let _url =  '/sys/menu/userMenu';
            this.$http.get(_url)
                .then((response) => {
                    if (response.code === 0) {
                        this.infos.tableData = this.infos.re_tableData = response.data.menu_info;
                        this.isAdmin = response.data.admin;
                        this.pageConfig.total = this.infos.re_tableData.length;
                        this.listLoading = false;
                        this.pageChange(this.pageConfig.curPage);
                    } else {
                        this.listLoading = false;
                        console.log(response.statusText)
                    }
                }).catch((response) => {
                    setTimeout(() => {
                        this.listLoading = false;
                    }, 400);
                    console.log(response)
                })
        },
        getPreMenuList() {
            let _url =  '/sys/menu/topLevel';
            this.$http.get(_url)
                .then((response) => {
                    if (response.code === 0) {
                        this.preMenuLists = response.data;
                    } else {
                        console.log(response.statusText)
                    }
                }).catch((response) => {
                    console.log(response)
                })
        },
        filterData() {
            this.infos.re_tableData = this.infos.tableData.filter((item) => {
                return item.menuName.indexOf(this.searchMsg) > -1;
            });
            this.pageConfig.total = this.infos.re_tableData.length;
            this.pageChange(this.pageConfig.curPage);
        },
        createMenu() {
            this.resetForm();
            this.menuEditVisible = true;
            this.getPreMenuList();
        },
        editMenu(info) {
            this.menuEditVisible = true;
            this.resetForm();
            this.menuInfo = JSON.parse(JSON.stringify(info));
            this.menuInfo.disabled = true;
            this.menuInfo.sort = Number(this.menuInfo.sort);
            this.menuInfo.type = 'edit';
            this.getPreMenuList();
        },
        sortChange(row, type) {
            let _url =  '/sys/menu/sort';
            row.sortBy = type;
            this.$http.post(_url, row).then((response) => {
                if (response.code === 0) {
                    this.getMenuList();
                    this.showMessage('更改成功!', 'success');
                } else {
                    console.log(response.statusText)
                }
            }).catch((response) => {
                console.log(response)
            })
        },
        stateSwitch(scope, state) {
            let useTag = scope.row.useTag === '0' ? "1" : "0";
            let _url =  '/sys/menu/' + scope.row.menuId + '/' + useTag;
            this.$http.put(_url).then((response) => {
                if (response.code === 0) {
                    this.showMessage('更改成功!', 'success');
                    scope.row.useTag = scope.row.useTag === '0' ? "1" : "0";
                } else {
                    console.log(response.statusText)
                }
            }).catch((response) => {
                console.log(response)
            })
        },
        // 删除机房相关操作
        deleteConfirm(info) {
            const h = this.$createElement;
            this.$msgbox({
                title: '删除菜单',
                message: h('p', null, [
                    h('span', null, '是否删除 '),
                    h('span', { style: 'color: #20A0FF;font-size:1.2em;font-weight:bold' }, info.menuName),
                    h('span', null, ' 这个菜单？'),
                ]),
                type: 'warning',
                showCancelButton: true,
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                beforeClose: (action, instance, done) => {
                    if (action === 'confirm') {
                        instance.confirmButtonLoading = true;
                        instance.confirmButtonText = '删除中...';
                        setTimeout(() => {
                            done();
                            setTimeout(() => {
                                instance.confirmButtonLoading = false;
                            }, 100);
                        }, 400);
                    } else {
                        done();
                    }
                }
            }).then((action) => {
                if (action === 'confirm') {
                    this.menuDelete(info.menuId);
                } else {
                    showMessage('已取消删除', 'info');
                }
            }).catch(() => {
                this.$message({
                    type: 'info',
                    message: '已取消删除'
                });
            });
        },
        menuDelete(menuId) {
            let _url =  '/sys/menu';
            this.$http.delete(_url + '/' + menuId).then((response) => {
                if (response.code === 0) {
                    this.getMenuList();
                    this.showMessage('删除成功!', 'success');
                } else {
                    if (response.code === -1) {
                        console.log(response.statusText);
                    } else {
                        this.showWarning(response.msg, '删除失败');
                    }
                }
            }).catch((response) => {
                console.log(response)
            })
        },
        handleSizeChange() {
            console.log('');
        },
        handleCurrentChange(val) {
            this.pageConfig.curPage = val;
            this.pageChange(val);
        },
        pageChange(page) {
            this.infos.pageData = this.infos.re_tableData.slice((page - 1) * this.pageConfig.size, page * this.pageConfig.size);
        },
        submitForm(formName, type) {
            let _url =  '/sys/menu';
            _url += type === 'new' ? '' : '/update';
            this.$refs[formName].validate((valid) => {
                if (valid) {
                    this.$http.post(_url, this.menuInfo)
                        .then((response) => {
                            if (response.code === 0) {
                                this.menuEditVisible = false;
                                this.getMenuList();
                                this.showMessage('创建成功!', 'success');
                                if (type === 'new') {
                                    this.showMessage('创建成功!', 'success');
                                } else {
                                    this.showMessage('修改成功!', 'success');
                                }
                            } else {
                                this.showWarning(response.msg, '失败信息');
                            }
                        }).catch((response) => {
                            console.log(response)
                        })
                } else {
                    console.log('error submit!!');
                    return false;
                }
            });

        },
        resetForm() {
            this.preMenuLists = [],
                this.menuInfo = {
                    menuName: '',
                    menuUrl: '',
                    parentId: '',
                    sort: '',
                    icon: '',
                    disabled: false,
                    type: 'new'
                }
            if (this.$refs['menuInfo']) {
                this.$refs['menuInfo'].resetFields();
            }
        },
        showWarning(msg, title) {
            this.$alert(msg, title, {
                showConfirmButton: false,
                showCancelButton: true,
                cancelButtonText: '关闭',
            });
        },
        showMessage(msg, type) {
            this.$message({
                message: msg,
                type: type
            });
        },
    }
};

</script>

